<template>
  <div class="operation-contain">
    <div class="operation-btn">
      <el-button type="primary" size="mini" @click="expand">展开/折叠</el-button>
      <el-button type="primary" size="mini" @click="check('all')">全选</el-button>
      <el-button type="primary" size="mini" @click="check('not')">全不选</el-button>
    </div>
    <el-tree
      show-checkbox
      node-key="id"
      lazy
      :load="loadNode"
      :props="defaultProps"
      :expand-on-click-node="false"
      :check-on-click-node="true"
      :default-expand-all="list.isExpand"
      v-loading="list.loading"
      ref="tree"
      @check-change="checkChange">
    </el-tree>
    <div class="footer-btn">
      <el-button @click="cancel" size="medium">取 消</el-button>
      <el-button v-perms="'system:role:setRolePerm'" type="primary" @click="sure" :loading="loading" size="medium">确 定</el-button>
    </div>
  </div>
</template>

<script>
// import { mapActions } from 'vuex'
export default {
  data () {
    return {
      list: {
        levelOne: [],
        page: 1,
        size: 1000,
        loading: false,
        isExpand: true
      },
      defaultProps: {
        children: 'children',
        label: 'name',
        isLeaf: 'leaf'
      },
      loading: false,
      defaultChecks: [],
      permissions: [],
      permChecks: []
    }
  },
  updated () {
    this.detail()
  },
  methods: {
    // ...mapActions[{
    //   'getPerms': 'user/getPerms'
    // }],
    detail () { // 根据id获取角色下的菜单权限列表和接口权限列表详情
      this.$API({
        name: 'detailRole',
        paths: [this.$route.params.id],
        requireAuth: true
      }).then (res => {
        if (res.data.code === 200) {
          this.permissions = res.data.data.rp
          this.defaultChecked()
        } else {
          this.$message.error(res.data.msg)
        }
      }).catch(error => {
        this.$message.error(error)
      })
    },
    defaultChecked () { // 默认选中
      // this.$nextTick(() => {
        const arr = []
        this.permissions.forEach(item => {
            arr.push(item.id)
        })
        this.defaultChecks = arr
        this.$refs.tree.setCheckedKeys(arr)
      // })
    },
    async loadNode(node, resolve) { // 懒加载
      if (node.level === 0) {
        return resolve(await this.getTagList())
      } else if (node.level === 1) {
        return resolve(await this.getTagApiList(node.label))
      } else {
        return resolve([]) // 防止该节点没有子节点时一直转圈的问题出现
      }
    },
    expand () { // 展开/折叠
      this.list.isExpand = !this.list.isExpand
      const nodes = this.$refs.tree.store._getAllNodes()
      for (let i in nodes) {
        nodes[i].expanded = this.list.isExpand
      }
    },
    check (type) { // 全选或全不选
      switch (type) {
        case 'all':
          this.$nextTick(() => {
            this.$refs.tree.setCheckedNodes(this.list.levelOne)
          })
        break
        case 'not':
          this.$refs.tree.setCheckedKeys([])
        break
      }
    },
    checkChange () { // 节点选中状态发生变化时的回调
      this.$nextTick(() => {
        this.permChecks = [...this.$refs.tree.getCheckedKeys(), ...this.$refs.tree.getHalfCheckedKeys()]
      })
    },
    async getTagList () { // 获取所有接口所属模块
      this.list.loading = true
      const res = await this.$API({
        name: 'getApiTagList',
        requireAuth: true
      })
      const tags = res.data.data
      tags.forEach((item, index) => {
        item.name = item.ta
        item.id = index
        item.leaf = false
      })
      this.list.levelOne = tags
      this.list.loading = false
      return tags
    },
    async getTagApiList (tag) { // 查询模块下的接口列表
      const res = await this.$API({
        name: 'getTagApiList',
        data: {
          tag
        },
        requireAuth: true
      })
      const results = res.data.data
      results.forEach(item => {
        item.name
        item.id
        item.leaf = true
      })
      return results
    },
    // 再根据角色获取对应的菜单列表
    cancel () { // 取消
      this.$router.push({ path: '/system/role' })
    },
    async sure () { // 确定
      this.loading = true
      if (this.permChecks.length === 0) {
        this.permChecks = this.defaultChecks
      }
      let arr = []
      this.permChecks.forEach(item => {
        if (typeof item === 'string') { // 去除父子节点
          arr.push(item)
        }
      })
      this.permChecks = arr
      const res = await this.$API({
        name: 'setRolePerm',
        requireAuth: true,
        data: {
          roleId: this.$route.params.id,
          permIds: this.permChecks
        }
      })
      if (res.data.code === 200) {
        this.loading = false
        this.detail()
        // 重置权限
        // await this.getPerms(this.$route.params.id)
        await this.$store.dispatch('user/getPerms', this.$route.params.id)
        this.$notify.success('授权成功')
      } else {
        this.$message.error(res.data.msg)
      }
    }
  }
}
</script>
<style lang="scss" >
.operation-contain {
  // 修改el-tree 的图标
  .el-icon-caret-right::before {
    content: "\e723";
    font-size: 14px;
  }
}
</style>
<style lang="scss" scoped>
.operation-contain {
  height: 100%;
  display: flex;
  flex-direction: column;
  .operation-btn {
    margin-bottom: 15px;
    flex-shrink: 0;
  }
  .footer-btn {
    flex-shrink: 0;
    display: flex;
    justify-content: flex-end;
    margin-top: 15px;
  }
  .el-tree {
    flex: 1 1 auto;
    overflow-y: auto;
  }
}
</style>